#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"
#include "MQTTClient.h"
#include "mqtt_test.h"
#include "hi_gpio.h"  // 导入 GPIO 驱动头文件
#include "hi_io.h"    // 导入 IO 功能配置头文件

static MQTTClient mq_client;
unsigned char *onenet_mqtt_buf = NULL;
unsigned char *onenet_mqtt_readbuf = NULL;
int buf_size;

Network n;
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;

// 主题区分（控制灯和设备消息）
#define TOPIC_LED_CTRL "expand:mqtt01-team12-led"  // 客户端→设备：控制灯
#define TOPIC_DEVICE_MSG "expand:mqtt01-team12-msg"// 设备→客户端：状态消息

// LED 控制函数（根据指令设置 GPIO10 电平，替换为 Hi3861 实际宏）
void led_ctrl(const char *cmd)
{
    if (strcmp(cmd, "on") == 0) {
        hi_gpio_set_ouput_val(HI_GPIO_IDX_10, HI_GPIO_VALUE1);  // 高电平→灯亮（替换为 HI_GPIO_VALUE1）
        printf("[LED] Turn ON\r\n");
    } else if (strcmp(cmd, "off") == 0) {
        hi_gpio_set_ouput_val(HI_GPIO_IDX_10, HI_GPIO_VALUE0);  // 低电平→灯灭（替换为 HI_GPIO_VALUE0）
        printf("[LED] Turn OFF\r\n");
    } else {
        printf("[LED] Unsupported cmd: %s（仅支持\"on\"/\"off\"）\r\n", cmd);
    }
}

// 消息回调函数：接收控制指令，控制 LED
void mqtt_callback(MessageData *msg_data)
{
    if (msg_data == NULL || msg_data->message == NULL || msg_data->topicName == NULL) {
        printf("mqtt_callback: invalid message data\r\n");
        return;
    }

    // 打印接收的主题和消息
    printf("Received topic: %.*s\r\n", 
           msg_data->topicName->lenstring.len, 
           msg_data->topicName->lenstring.data);
    printf("Received message: %.*s\r\n", 
           msg_data->message->payloadlen, 
           (char *)msg_data->message->payload);

    // 仅处理“控制灯的主题”，解析指令
    if (strncmp(msg_data->topicName->lenstring.data, TOPIC_LED_CTRL, 
                msg_data->topicName->lenstring.len) == 0) {
        char cmd[16] = {0};
        strncpy(cmd, (char *)msg_data->message->payload, 
                msg_data->message->payloadlen < 15 ? msg_data->message->payloadlen : 15);
        led_ctrl(cmd);  // 控制灯
    }
}

int mqtt_connect(void)
{
    int rc = 0;

    // 初始化网络（依赖Paho MQTT的LiteOS适配层）
    NetworkInit(&n);
    // 连接EMQ公共MQTT服务器（无需注册，直接使用）
    NetworkConnect(&n, "broker.emqx.io", 1883);

    // 分配MQTT消息缓冲区（4096+1024=5120字节）
    buf_size = 4096 + 1024;
    onenet_mqtt_buf = (unsigned char *)malloc(buf_size);
    onenet_mqtt_readbuf = (unsigned char *)malloc(buf_size);
    if (!(onenet_mqtt_buf && onenet_mqtt_readbuf)) {
        printf("No memory for MQTT client buffer!\r\n");
        if (onenet_mqtt_buf) free(onenet_mqtt_buf);
        if (onenet_mqtt_readbuf) free(onenet_mqtt_readbuf);
        return -2;
    }

    // 初始化MQTT客户端
    MQTTClientInit(&mq_client, &n, 1000, 
                  onenet_mqtt_buf, buf_size, 
                  onenet_mqtt_readbuf, buf_size);

    // 启动MQTT后台任务（LiteOS适配层提供）
    MQTTStartTask(&mq_client);

    // 配置MQTT连接参数
    data.keepAliveInterval = 30;  // 心跳间隔30秒
    data.cleansession = 1;        // 清理会话（断开后不保留状态）
    data.clientID.cstring = "device12";  // 客户端ID（加LED标识，避免冲突）
    data.username.cstring = "device12";  // 用户名（自定义）
    data.password.cstring = "123456";      // 密码（自定义）

    // 设置默认消息回调函数
    mq_client.defaultMessageHandler = mqtt_callback;

    // 连接MQTT服务器
    rc = MQTTConnect(&mq_client, &data);
    if (rc != 0) {
        printf("MQTTConnect failed, rc=%d\r\n", rc);
        return rc;
    }
    printf("MQTT connected successfully!\r\n");

    // 订阅“控制灯的主题”（接收客户端指令）
    rc = MQTTSubscribe(&mq_client, TOPIC_LED_CTRL, 0, mqtt_callback);
    if (rc != 0) {
        printf("Subscribe to %s failed, rc=%d\r\n", TOPIC_LED_CTRL, rc);
        return rc;
    }
    printf("Subscribed to LED control topic: %s\r\n", TOPIC_LED_CTRL);

    // 循环发布设备状态（到“设备消息主题”）
    while (1) {
        MQTTMessage message;
        const char *payload = "hello! team12 LED is ready";  // 设备状态消息

        message.qos = 0;
        message.retained = 0;
        message.payload = (void *)payload;
        message.payloadlen = strlen(payload);

        // 发布消息到“设备消息主题”
        if (MQTTPublish(&mq_client, TOPIC_DEVICE_MSG, &message) < 0) {
            printf("MQTTPublish to %s failed!\r\n", TOPIC_DEVICE_MSG);
        } else {
            printf("Published to %s: %s\r\n", TOPIC_DEVICE_MSG, payload);
        }

        usleep(5000000);  // 5秒发一次（避免消息太频繁）
    }

    return 0;
}

// GPIO10 初始化（配置为输出模式，控制LED，替换为 Hi3861 实际宏）
void gpio10_led_init(void)
{
    hi_io_set_func(HI_GPIO_IDX_10, HI_IO_FUNC_GPIO_10_GPIO);  // GPIO10 设为GPIO功能
    hi_gpio_set_dir(HI_GPIO_IDX_10, HI_GPIO_DIR_OUT);        // 设为输出模式
    hi_gpio_set_ouput_val(HI_GPIO_IDX_10, HI_GPIO_VALUE0);  // 初始状态：灯灭（替换为 HI_GPIO_VALUE0）
    printf("GPIO10 LED initialized: OFF\r\n");
}

void mqtt_test(void)
{
    // 初始化LED（MQTT连接前确保引脚就绪）
    gpio10_led_init();
    // 连接MQTT服务器
    mqtt_connect();
}